package com.iot.ic.service;


import com.iot.ic.common.Constant;
import com.iot.ic.common.Options;
import com.iot.ic.common.Response;
import com.iot.ic.dao.StadiumResultMapper;
import com.iot.ic.model.Device;
import com.iot.ic.model.IllegalResult;
import com.iot.ic.model.ManualIntervention;
import com.iot.ic.model.MatchPause;
import com.iot.ic.model.ScenesResult;
import com.iot.ic.model.StadiumResult;
import com.iot.ic.model.TeamInfo;
import com.iot.ic.utils.DatetimeUtil;
import com.iot.ic.utils.response.ResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * Created by xiuge on 2017/2/20.
 */
@Service
public class StadiumResultServiceImpl implements StadiumResultService {

    @Autowired
    private StadiumResultMapper stadiumResultMapper;
    @Autowired
    private ScenesResultService scenesResultService;
    @Autowired
    private IllegalResultService illegalResultService;
    @Autowired
    private IllegalResultShowService illegalResultShowService;
    @Autowired
    private MatchPauseService matchPauseService;
    @Autowired
    private TeamService teamService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
  	SimpMessagingTemplate simpMessagingTemplate;

    @Override
    public int startRacing(StadiumResult stadiumResult) {
    	long startTime = System.currentTimeMillis();
        StadiumResult oldStadiumResult = getStadiumResultByTeamAndStadium(stadiumResult.getTeamId(), stadiumResult.getStadiumId());
        if (oldStadiumResult != null) {
        	//旧的比赛成绩设为已删除
        	oldStadiumResult.setDelFlag(Options.Deleted.getCode());
        	stadiumResultMapper.updateByPrimaryKeySelective(oldStadiumResult);
        	List<ScenesResult> scenesResultList = scenesResultService.listScenesResultByStadiumResult(oldStadiumResult.getStadiumResultId());
        	for (ScenesResult scenesResult : scenesResultList) {
        		illegalResultShowService.deleteIllegalResultShow(scenesResult.getScenesResultId());
        		scenesResultService.deleteScenesResult(scenesResult.getScenesResultId());
        		illegalResultService.deleteIllegalResultByScenesResultId(scenesResult.getScenesResultId());
			}
        }
        stadiumResult.setCreateTime(new Date());
        stadiumResult.setStartTime(new Date());
        stadiumResult.setDelFlag(Options.NotDel.getCode());
        stadiumResult.setTotalScore(0);
        stadiumResult.setMatchState(Options.Start.getCode());
        stadiumResult.setCompleteFlag(0);
        stadiumResult.setScenesScore(0);
        stadiumResult.setTimeScore(0);
        stadiumResult.setRoadScore(0);
		long endTime = System.currentTimeMillis();
		System.out.println("耗时："+(endTime -startTime));
        int result = stadiumResultMapper.insert(stadiumResult);
        if (result > 0) {
            //获得赛场比赛结果ID
            result = stadiumResult.getStadiumResultId();
        }
        
        //修改车队状态
		TeamInfo teamInfo = new TeamInfo();
		teamInfo.setTeamId(stadiumResult.getTeamId());
		teamInfo.setTeamState(Options.Normal.getCode());
		teamService.updateTeam(teamInfo);
		
		//websocket推送
		Map<String,Integer> teamStateMap = new HashMap<String,Integer>();
		teamStateMap.put("teamState", Options.Normal.getCode());
		simpMessagingTemplate.convertAndSendToUser(stadiumResult.getTeamId().toString(), "/testTeamStatesocketpush", teamStateMap);
		
		
		Map<String,String> refereeNameMap = new HashMap<String,String>();
		refereeNameMap.put("refereeName", stadiumResult.getRefereeName());
		simpMessagingTemplate.convertAndSendToUser(stadiumResult.getTeamId().toString(), "/testRefereeNamesocketpush", refereeNameMap);

        return result;
    }

    @Override
    public int updateStadiumResult(StadiumResult stadiumResult) {
        int result = stadiumResultMapper.updateByPrimaryKeySelective(stadiumResult);
        return result;
    }

    @Override
    public StadiumResult getStadiumResult(int stadiumResultId) {
        StadiumResult stadiumResult = stadiumResultMapper.selectByPrimaryKey(stadiumResultId);
        return stadiumResult;
    }

    @Override
    public int endRacing(StadiumResult stadiumResult) {
    	  stadiumResult.setEndTime(new Date());
          stadiumResult.setMatchState(Options.Finished.getCode());
    	
    	MatchPause matchPause = new MatchPause();
		matchPause.setStadiumResultId(stadiumResult.getStadiumResultId());
		List<MatchPause> matchPauseList =  matchPauseService.listMatchPause(matchPause);
		int pauseTime = 0;
		for (MatchPause matchPauseData : matchPauseList) {
			long startTime = matchPauseData.getStartTime().getTime();
			long endTime = matchPauseData.getEndTime().getTime();
			int pauseTimeData = (int) (endTime - startTime)/1000;
			pauseTime = pauseTime + pauseTimeData;
		}
		StadiumResult oldStadiumResult = stadiumResultMapper.selectByPrimaryKey(stadiumResult.getStadiumResultId());
		long startTime = oldStadiumResult.getStartTime().getTime();
		long endTime = stadiumResult.getEndTime().getTime();
		int matchTime = (int) ((endTime - startTime)/1000);
		matchTime = matchTime - pauseTime;
		stadiumResult.setMatchTime(matchTime);
		
		//更改车对状态
		TeamInfo teamInfo = new TeamInfo();
		teamInfo.setTeamId(oldStadiumResult.getTeamId());
		teamInfo.setTeamState(Options.Finish.getCode());
		teamService.updateTeam(teamInfo);
		
		//解绑设备
		List<Device> deviceList = deviceService.getDeviceListByTeamId(oldStadiumResult.getTeamId());
		for (Device device : deviceList) {
			deviceService.unBindDeviceWithTeam(device.getDeviceId());
		}
		 
        int result = stadiumResultMapper.updateByPrimaryKeySelective(stadiumResult);
      //websocket推送
  		Map<String,Integer> teamStateMap = new HashMap<String,Integer>();
  		teamStateMap.put("teamState", Options.Finish.getCode());
  		simpMessagingTemplate.convertAndSendToUser(oldStadiumResult.getTeamId().toString(), "/testTeamStatesocketpush", teamStateMap);
        
  		Response response=new Response();
  		List<Map<String,Object>> list = getStadiumResultDetailByYear(2017);
  		response.setResult(list);
  		simpMessagingTemplate.convertAndSend("/topic/testStadiumResultSocketpush", response);
  		if (oldStadiumResult.getStadiumId() == Options.CityStadium.getCode()) {
  			List<Map<String,Object>> stadiumDataResultList = getStadiumResultDetailByStadiumType(1);
  			response.setResult(stadiumDataResultList);
  			simpMessagingTemplate.convertAndSend("/topic/testStadiumResult1Socketpush", response);
  		} else if (oldStadiumResult.getStadiumId() == Options.HighSpeedStadium.getCode()) {
  			List<Map<String,Object>> stadiumDataResultList = getStadiumResultDetailByStadiumType(2);
  			response.setResult(stadiumDataResultList);
  			simpMessagingTemplate.convertAndSend("/topic/testStadiumResul2Socketpush", response);
  		} else if (oldStadiumResult.getStadiumId() == Options.Suburbs.getCode()) {
  			List<Map<String,Object>> stadiumDataResultList = getStadiumResultDetailByStadiumType(3);
  			response.setResult(stadiumDataResultList);
  			simpMessagingTemplate.convertAndSend("/topic/testStadiumResul3Socketpush", response);
  		}
        return result;
    }

    @Override
    public List<StadiumResult> listStadiumResultByTeam(int teamId) {
        List<StadiumResult> resultList = stadiumResultMapper.listStadiumResultByTeam(teamId);
        return resultList;
    }

	@Override
	public Map<String, Object> getStadiumResultByTeam(int teamId, int stadiumResultId) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		List<StadiumResult> resultList = stadiumResultMapper.listStadiumResultByTeam(teamId);
		StadiumResult stadiumResultData = stadiumResultMapper.selectByPrimaryKey(stadiumResultId);
		resultMap.put("refereeName", stadiumResultData.getRefereeName());
		int matchState = 0;
		if (resultList != null && resultList.size() > 0) {
			StadiumResult dataStadiumResult =  resultList.get(0);
			resultMap.put("teamName", dataStadiumResult.getTeamName());
			int stadium1Score = 0;
			int stadium2Score = 0;
			int totalScore = 0;
			for (StadiumResult stadiumResult : resultList) {
				matchState = stadiumResult.getMatchState();
				if (stadiumResult.getStadiumId() == Options.CityStadium.getCode()) {
					stadium1Score = stadiumResult.getTotalScore();
				} else if (stadiumResult.getStadiumId() == Options.HighSpeedStadium.getCode()) {
					stadium2Score = stadiumResult.getTotalScore();
				}
			}
			if (resultList.size() == 2) {
				resultMap.put("matchState", matchState);
			} else {
				resultMap.put("matchState", Options.Start.getCode());
			}
			totalScore = stadium1Score + stadium2Score;
			resultMap.put("stadium1Score", stadium1Score);
			resultMap.put("stadium1RoadScore", stadiumResultData.getRoadScore());
			resultMap.put("stadium1ScenesScore", stadiumResultData.getScenesScore());
			resultMap.put("timeScore", stadiumResultData.getTimeScore());
			resultMap.put("stadium2Score", stadium2Score);
			resultMap.put("totalScore", totalScore);
		}
		return resultMap;
	}

    public List<Map<String, Object>> getStadiumResultByYear(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, 0, 0);
        Date start = calendar.getTime();
        calendar.set(year + 1, 0, 0);
        Date end = calendar.getTime();
        List<Integer> teamIds = new ArrayList<>();
        List<Map<String, Object>> list = stadiumResultMapper.selectTeamCount(start, end);
        for (Map<String, Object> map : list) {
           // if ((long) map.get("count") == Constant.stadiumNum)
                teamIds.add((int) map.get("teamId"));
        }
        List<Map<String, Object>> stadiumResults=new ArrayList<>();
        if (teamIds!=null&&teamIds.size()!=0){
            stadiumResults= stadiumResultMapper.selectStadiumResultByTeam(teamIds);
        }
        return stadiumResults;
    }

    @Override
    public List<Map<String, Object>> getStadiumResultDetailByYear(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year, 0, 0);
        Date start = calendar.getTime();
        calendar.set(year + 1, 0, 0);
        Date end = calendar.getTime();
        List<Integer> teamIds = new ArrayList<>();
        List<Map<String, Object>> list = stadiumResultMapper.selectTeamCount(start, end);
        if (list==null||list.size()==0){
            return  new ArrayList<Map<String, Object>>();
        }
        for (Map<String, Object> map : list) {
          //  if ((long) map.get("count") == Constant.stadiumNum)
                teamIds.add((int) map.get("teamId"));
        }
        List<StadiumResult> stadiumResults = stadiumResultMapper.selectStadiumResultDetailByTeam(teamIds);
        Map<Integer,Map<String,Object>>resultMap = new HashMap<>();
		for (int i=0;i<stadiumResults.size();i++) {
            StadiumResult item = stadiumResults.get(i);
			Map<String,Object>stadiumResult= ResponseUtil.getResultMap(item,false);
			int teamId = (int)stadiumResult.get("teamId");
			if (!resultMap.containsKey(teamId)) {
                resultMap.put(teamId, stadiumResult);
                stadiumResult.put("stadium"+item.getStadiumId()+"Score", item.getTotalScore());
                stadiumResult.put("stadium"+item.getStadiumId()+"Time", item.getMatchTime());
            }else{
                int totalScore=((int)stadiumResult.get("totalScore")+(int)resultMap.get(teamId).get("totalScore"));
                stadiumResult=resultMap.get(teamId);
				stadiumResult.put("totalScore",totalScore);
                stadiumResult.put("stadium"+item.getStadiumId()+"Score", item.getTotalScore());
                stadiumResult.put("stadium"+item.getStadiumId()+"Time", item.getMatchTime());
				resultMap.put(teamId,stadiumResult);
			}
		}
		
		
		List<Map<String,Object>>resultList=new ArrayList<>();
		for (Integer teamId :resultMap.keySet()) {
			resultList.add(resultMap.get(teamId));
		}
		Collections.sort(resultList, new Comparator<Map<String,Object>>() {
			@Override
			public int compare(Map<String, Object> o1, Map<String, Object> o2) {
				return Integer.parseInt(o2.get("totalScore").toString()) - Integer.parseInt(o1.get("totalScore").toString()) ;
			}
		
        });
        return resultList;
    }

    @Override
    public StadiumResult getStadiumResultByTeamAndStadium(int teamId, int stadiumId) {
        StadiumResult stadiumResult = new StadiumResult();
        stadiumResult.setStadiumId(stadiumId);
        stadiumResult.setTeamId(teamId);
        StadiumResult stadiumResultData = stadiumResultMapper.getStadiumResultByTeamAndStadium(stadiumResult);
        return stadiumResultData;
    }


    @Override
    public List<StadiumResult> getStadiumResultWithScenesResult(int teamId) {
        List<StadiumResult> list = stadiumResultMapper.selectStadiumResultWithScenes(teamId);
        for (StadiumResult stadiumResult : list) {
        	int roadScore = 0;
        	int scenesScore = 0;
            List<ScenesResult> scenesResults = stadiumResult.getScenesResultList();
            for (ScenesResult scenesResult :scenesResults) {
            	if (scenesResult.getScenesType() == Options.Road.getCode()) {
            		roadScore = roadScore + scenesResult.getScenesResult();
            	} else {
            		scenesScore = scenesScore + scenesResult.getScenesResult();
            	}
                List<IllegalResult> illegalResults = scenesResult.getIllegalResultList();
                int illegalScore = 0;
                if (illegalResults != null&&illegalResults.size()!=0) {
                    for (IllegalResult illegalResult :
                            illegalResults) {
                        if (illegalResult.getIllegalCount()!=null&&illegalResult.getIllegalScore()!=null)
                            illegalScore += illegalResult.getIllegalScore()*illegalResult.getIllegalCount();
                    }
                }
                List<ManualIntervention> manualInteventions = scenesResult.getManualInterventionList();
                if (manualInteventions != null){
                    scenesResult.setManualInterventionCount(manualInteventions.size());
                }
                scenesResult.setIllegalScore(illegalScore);
                scenesResult.setManualInterventionCount(manualInteventions.size());
                scenesResult.setIllegalResultList(new ArrayList<>());
                scenesResult.setManualInterventionList(new ArrayList<>());
            }
            stadiumResult.setScenesScore(scenesScore);
        }
        return list;
    }

    public int updateStadiumResult(int stadiumResultId,int scoreChange, int scenesScoreChange, int roadScoreChange){
        int result=stadiumResultMapper.updateStadiumResultScore(stadiumResultId,scoreChange, scenesScoreChange, roadScoreChange);
        return result;
    }

	@Override
	public List<Map<String, Object>> getStadiumResultDetailByStadiumType(int stadiumType) {
		List<Map<String,Object>> resultList = stadiumResultMapper.listStadiumResultByStadiumType(stadiumType);
		return resultList;
	}

	@Override
	public StadiumResult getStadiumResultLeastByTeamId(int teamId) {
		StadiumResult stadiumResult = stadiumResultMapper.getStadiumResultLeastByTeam(teamId);
		return stadiumResult;
	}

	@Override
	public StadiumResult getStadiumResultWithScenesResult(int teamId, int stadiumId) {
		Map<String,Object> totalScoreMap = stadiumResultMapper.selectTeamTotalScore(teamId);
        StadiumResult stadiumResult = stadiumResultMapper.selectStadiumResultWithScenesbyStadium(teamId, stadiumId);   
        if (stadiumResult != null) {
        	String teamTotalScore = totalScoreMap.get("totalScore").toString();
        	stadiumResult.setTeamTotalScore(Integer.parseInt(teamTotalScore) );
    		int roadScore = 0;
        	int scenesScore = 0;
            List<ScenesResult> scenesResults = stadiumResult.getScenesResultList();
            for (ScenesResult scenesResult :scenesResults) {
            	if (scenesResult.getScenesType() == Options.Road.getCode()) {
            		roadScore = roadScore + scenesResult.getScenesResult();
            	} else {
            		scenesScore = scenesScore + scenesResult.getScenesResult();
            	}
                List<IllegalResult> illegalResults = scenesResult.getIllegalResultList();
                int illegalScore = 0;
                if (illegalResults != null&&illegalResults.size()!=0) {
                    for (IllegalResult illegalResult :
                            illegalResults) {
                        if (illegalResult.getIllegalCount()!=null&&illegalResult.getIllegalScore()!=null)
                            illegalScore += illegalResult.getIllegalScore()*illegalResult.getIllegalCount();
                    }
                }
                List<ManualIntervention> manualInteventions = scenesResult.getManualInterventionList();
                if (manualInteventions != null){
                    scenesResult.setManualInterventionCount(manualInteventions.size());
                }
                scenesResult.setIllegalScore(illegalScore);
                scenesResult.setManualInterventionCount(manualInteventions.size());
                scenesResult.setIllegalResultList(new ArrayList<>());
                scenesResult.setManualInterventionList(new ArrayList<>());
                }
    	} else {
    		String teamTotalScore = totalScoreMap.get("totalScore").toString();
    		List<StadiumResult> list = stadiumResultMapper.selectStadiumResultWithScenes(teamId);
    		StadiumResult resultStadium = list.get(0);
    		stadiumResult = new StadiumResult();
    		stadiumResult.setTeamName(resultStadium.getTeamName());
    		stadiumResult.setRefereeName(resultStadium.getRefereeName());
    		stadiumResult.setTeamTotalScore(Integer.parseInt(teamTotalScore));
    	}
	    return stadiumResult;
	}
}
